package edu.johnpank.libassistant.controllers

import edu.johnpank.libassistant.entity.User
import edu.johnpank.libassistant.enums.Role
import edu.johnpank.libassistant.services.UserService
import edu.johnpank.libassistant.util.UserValidator
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.ComponentScan
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.validation.BindingResult
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ModelAttribute
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import javax.validation.Valid

@Controller
@ComponentScan
class AdminController(
    @Autowired
    private val userService: UserService,
    private val passwordEncoder: PasswordEncoder,
    private val userValidator: UserValidator
) {

    //region showMainPage
    @GetMapping("admin/admin_main_page")
    fun showMainAdminPage(): String{
        return "admin/admin_main_page"
    }
    //endregion

    //region addLibrarian
    @GetMapping("admin/addLibrAdmin")
    fun showAddLibrarianOrAdminPage(@ModelAttribute("newLibrarian") user: User): String{
        println("add libr")
        return "admin/add_libr_admin_page"
    }

    @PostMapping("admin/addLibrAdmin")
    fun addLibrarianOrAdmin(@ModelAttribute("newLibrarian") @Valid user: User,
                            bindingResult: BindingResult,
                            model: Model
    ): String {
        user.password = passwordEncoder.encode(user.password)
        if (user.isAdmin) user.roles.add(Role.ROLE_ADMIN)
        if (user.isLibrarian) user.roles.add(Role.ROLE_LIBRARIAN)

        userValidator.validate(user, bindingResult)

        if (bindingResult.hasErrors())
            return "admin/add_libr_admin_page"

        userService.addUser(user)

        return "redirect:/admin/addLibrAdmin"
    }
    //endregion

    //region showUserList
    @GetMapping("admin/userListPage")
    fun showUserListPage(model: Model): String{
        model.addAttribute("users", userService.getAllUser().toList())
        return "admin/user_list_page"
    }
    //endregion

    //region editUser
    @GetMapping("admin/showUserInfo")
    fun showUserInfoPage(@RequestParam("userId") id: Long,
                         model: Model): String{
        model.addAttribute("user", userService.getUserById(id))

        return "admin/edit_user_page"
    }

    @PostMapping("admin/updateUser")
    fun updateUserInfo(@ModelAttribute("user") user: User,
                            bindingResult: BindingResult,
                            model: Model
    ): String {

        val updatingUser = userService.getUserByLogin(user.login).get()
        updatingUser.login = user.login
        updatingUser.firstName = user.firstName
        updatingUser.lastName = user.lastName
        updatingUser.login = user.login
        updatingUser.email = user.email
        updatingUser.isAdmin = user.isAdmin
        updatingUser.isLibrarian = user.isLibrarian
        updatingUser.isConfirmed = user.isConfirmed
//        updatingUser.regDate = user.regDate

        if (user.password.length < 59) updatingUser.password = passwordEncoder.encode(user.password) else updatingUser.password = user.password

        updatingUser.roles.clear()
        if (updatingUser.isAdmin) updatingUser.roles.add(Role.ROLE_ADMIN)
        if (updatingUser.isLibrarian) updatingUser.roles.add(Role.ROLE_LIBRARIAN)

        if (bindingResult.hasErrors())
            return "admin/edit_user_page"

        userService.updateUser(updatingUser)

        return "redirect:/admin/userListPage"
    }
    //endregion

    //region deleteUser
    @GetMapping("admin/deleteUser")
    fun deleteUser(@RequestParam("userId") id: Long,
                         model: Model): String{
        val user = userService.getUserById(id)
        userService.deleteUser(user)

        return "redirect:/admin/userListPage"
    }
    //endregion

    //region findUser
    @GetMapping("admin/findUserPage")
    fun showFindUserPage(model: Model): String{
        return "admin/find_user_page"
    }

    @GetMapping("admin/findUser")
    fun showFindUserResultPage(@RequestParam("search") search: String,
                               model: Model): String{

        model.addAttribute("users", userService.findUserByString(search))
        return "admin/user_list_page"
    }
    //endregion
}